package com.classes;

import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TreeMap;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import com.mbbmap.app.manager.ConfigManager;
import com.mbbmap.app.manager.DBConnectionManager;
import com.mbbmap.util.Constants;

public class MerchantFactory {
	private String message;
	private long merchantID = 0;
	private long caseID = 0;
	private static final String CONFIG_FILE = "/system.properties";
	private static final java.util.Properties appCfg = new java.util.Properties();
	
	public String getMessage() {
		return "[MerchantFactory] " + this.message; 
	}
	
	public long getMerchantID() {
		return this.merchantID; 
	}
	
	public long getCaseID() {
		return this.caseID; 
	}
	
	public boolean newMerchantCase(TreeMap<String, String> post, String firstAction, String user, String userGroup, String countryCode){
		return this.newMerchantCase(post, firstAction, user, userGroup, countryCode, "");
	}
	
	public boolean newMerchantCase(TreeMap<String, String> post, String firstAction, String user, String userGroup, String countryCode, String refSuffix){
		String start_action = null;
		String start_status = null;
		String start_extcode = null;
		
		try {
	        int TIMEOUT = 10000; //DB connection timeout if unable to get connection in less than 10 seconds
	        String connectionPool = ConfigManager.getInstance().getConnectionPool();
	        DBConnectionManager connMgr = DBConnectionManager.getInstance();
	        try { TIMEOUT = Integer.parseInt(ConfigManager.getInstance().get(Constants.DB_WAIT_TIME)); } catch (Exception e) {}
	        Connection conn = connMgr.getConnection(connectionPool, TIMEOUT);
			
			try {
				String sql = "select * from statusmast "
						+ "where s_current = '_START_' "
						+ "and s_action = ? "
						+ "and s_branch = 1";
				
				PreparedStatement statement = conn.prepareStatement(sql);
				
				try {
					statement.setString(1, firstAction);
					
					ResultSet resultSet = statement.executeQuery();
					
					try {
						if(resultSet.next()){
							start_action = resultSet.getString("s_action");
							start_status = resultSet.getString("s_next");
							start_extcode = resultSet.getString("maxis_code");
						}
					} finally {
						resultSet.close();
					}
					
				} finally {
					statement.close();
				}
				
				
				int next_seq = 1;
				
				sql = "select * from casemast where c_created_date >= to_date(current_date)";
				
				statement = conn.prepareStatement(sql);
				
				try {
					ResultSet resultSet = statement.executeQuery();
					
					try {
						while(resultSet.next()) {
							next_seq++;
						}
					} finally {
						resultSet.close();
					}
				} finally {
					statement.close();
				}
				
				String next_seq_str = String.format("%04d", next_seq);
				
				SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
				String yyyymmdd = format.format(new Date());
				
				String ref_no = yyyymmdd + countryCode + next_seq_str + refSuffix;
				System.out.println("Reference No: " + ref_no);
				
				
				sql = "insert into merchant (m_name, m_ownership_status, m_reg_no, m_desc, m_mcc_code, m_paid_up_capital, m_year_in_business, m_recall_barcode, m_avg_ticket_size, m_curr_bank, m_curr_no, m_curr_avg_deposit, m_curr_dtl_deposit, m_amex_auth_sign, m_created_date, m_created_by, m_modified_date, m_modified_by, m_gst_registration, m_rmcd_approval_no) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, ?, sysdate, ?, ?, ?)";
				
				statement = conn.prepareStatement(sql);
				
				try {
					statement.setString(1, post.get("registered_name"));
					statement.setString(2, post.get("ownership_status"));
					statement.setString(3, post.get("registered_no"));
					statement.setString(4, post.get("nature_of_business"));
					statement.setString(5, post.get("mcc_code"));
					statement.setDouble(6, (post.get("paid_up_capital").length() <= 0 ? 0.00 : Double.parseDouble(post.get("paid_up_capital"))));
					statement.setString(7, post.get("years_in_business"));
					statement.setString(8, post.get("recall_barcode_no"));
					statement.setString(9, post.get("avr_ticket_size"));
					statement.setString(10, post.get("bank_name"));
					statement.setString(11, post.get("current_acc_no"));
					statement.setDouble(12, (post.get("avr_monthly_deposit").length() <= 0 ? 0.00 : Double.parseDouble(post.get("avr_monthly_deposit"))));
					statement.setString(13, post.get("monthly_deposit_entries"));
					statement.setString(14, post.get("amex_auth_sign"));
					statement.setString(15, user);
					statement.setString(16, user);
					statement.setString(17, post.get("gst_registration"));
					statement.setString(18, post.get("rmcd_approval_no"));
					
					statement.execute();
				} finally {
					statement.close();
				}
				
				Long merchant_id = null;
				Statement statement2 = conn.createStatement();
				
				try {
					ResultSet generatedKeys = statement2.executeQuery("SELECT SEQ_MERCHANT.CURRVAL FROM DUAL");
					try {
						if (generatedKeys.next()) {
							merchant_id = new Long(generatedKeys.getLong(1));
						}
					} finally {
						generatedKeys.close();
					}
				} finally {
					statement2.close();
				}
				
				this.merchantID = merchant_id;
				System.out.println("Inserted Merchant ID: " + this.merchantID);
				
				
				JSONObject merchant_dtl_obj = new JSONObject();
				merchant_dtl_obj.put("ownership_status", post.get("ownership_status"));
				merchant_dtl_obj.put("registered_name", post.get("registered_name"));
				merchant_dtl_obj.put("registered_no", post.get("registered_no"));
				merchant_dtl_obj.put("desc", post.get("nature_of_business"));
				merchant_dtl_obj.put("mcc_code", post.get("mcc_code"));
				merchant_dtl_obj.put("paid_up_capital", post.get("paid_up_capital"));
				merchant_dtl_obj.put("recall_barcode", post.get("recall_barcode_no"));
				merchant_dtl_obj.put("year_in_business", post.get("years_in_business"));
				merchant_dtl_obj.put("avg_ticket_size", post.get("avr_ticket_size"));
				merchant_dtl_obj.put("curr_bank", post.get("bank_name"));
				merchant_dtl_obj.put("curr_acc_no", post.get("current_acc_no"));
				merchant_dtl_obj.put("curr_avg_deposit", post.get("avr_monthly_deposit"));
				merchant_dtl_obj.put("gst_registration", post.get("gst_registration"));
				merchant_dtl_obj.put("rmcd_approval_no", post.get("rmcd_approval_no"));
				
				JSONArray avg_deposit_json = (JSONArray)JSONValue.parse(post.get("monthly_deposit_entries"));
				merchant_dtl_obj.put("curr_avg_deposit_dtl", avg_deposit_json);
				
				String merchant_dtl = merchant_dtl_obj.toString();
				
				sql = "insert into casemast (c_merchant_id, c_type, c_acquirer, c_merchant_details, c_amex_auth_sign, c_action, c_status, c_created_date, c_created_by, c_modified_date, c_modified_by, c_group_code, c_reference_no, c_country_code, c_last_reference_no, c_reseller_location, c_ext_ref_no, c_ext_code) "
					+ "values (?, ?, ?, ?, ?, ?, ?, sysdate, ?, sysdate, ?, ?, ?, ?, ?, ?, ?, ?)";
				
				statement = conn.prepareStatement(sql);
				
				try {
					statement.setInt(1, Integer.parseInt(this.merchantID + ""));
					statement.setString(2, post.get("app_type"));
					statement.setString(3, post.get("current_acquirer"));
					statement.setString(4, merchant_dtl);
					statement.setString(5, post.get("amex_auth_sign"));
					statement.setString(6, start_action);
					statement.setString(7, start_status);
					statement.setString(8, user);
					statement.setString(9, user);
					statement.setString(10,  userGroup);
					statement.setString(11, ref_no);
					statement.setString(12, countryCode);
					statement.setString(13, post.get("last_ref_no") != null && post.get("last_ref_no").length() > 0 ? post.get("last_ref_no") : null);
					statement.setString(14, post.get("reseller_location") != null && post.get("reseller_location").length() > 0 ? post.get("reseller_location") : null);
					statement.setString(15, post.get("ext_ref_no") != null && post.get("ext_ref_no").length() > 0 ? post.get("ext_ref_no") : null);
					statement.setString(16, start_extcode);
					
					statement.execute();
				} finally {
					statement.close();
				}
				
				Long case_id = null;
				statement2 = conn.createStatement();
				
				try {
					ResultSet generatedKeys = statement2.executeQuery("SELECT SEQ_CASEMAST.CURRVAL FROM DUAL");
					try {
						if (generatedKeys.next()) {
							case_id = new Long(generatedKeys.getLong(1));
						}
					} finally {
						generatedKeys.close();
					}
				} finally {
					statement2.close();
				}
				
				
				this.caseID = case_id;
				System.out.println("Inserted Case ID: " + this.caseID);
			
			} finally {
				connMgr.freeConnection(connectionPool, conn);
			}
			
			return true;
			
		} catch (Exception e){
			this.message = e.getMessage();
			return false;
		}
	}
	
	public Merchant getMerchant(int merchant_id) {
		try {
	        int TIMEOUT = 10000; //DB connection timeout if unable to get connection in less than 10 seconds
	        String connectionPool = ConfigManager.getInstance().getConnectionPool();
	        DBConnectionManager connMgr = DBConnectionManager.getInstance();
	        try { TIMEOUT = Integer.parseInt(ConfigManager.getInstance().get(Constants.DB_WAIT_TIME)); } catch (Exception e) {}
	        Connection conn = connMgr.getConnection(connectionPool, TIMEOUT);
			
			try {
				String sql = "select * from merchant where m_id = ?";
				
				PreparedStatement statement = conn.prepareStatement(sql);
				
				try {
					statement.setInt(1, merchant_id);
					
					ResultSet resultSet = statement.executeQuery();
					
					try {
						if(resultSet.next()){
							Merchant a = new Merchant();
							
							a.setOwnershipStatus(resultSet.getString("m_ownership_status"));
							a.setRegisteredName(resultSet.getString("m_name"));
							a.setRegisteredNo(resultSet.getString("m_reg_no"));
							a.setDesc(resultSet.getString("m_desc"));
							a.setMCCCode(resultSet.getString("m_mcc_code"));
							a.setPaidUpCapital(resultSet.getString("m_paid_up_capital"));
							a.setRecallBarcode(resultSet.getString("m_recall_barcode"));
							a.setYearInBusiness(resultSet.getString("m_year_in_business"));
							a.setAvgTicketSize(resultSet.getString("m_avg_ticket_size"));
							a.setCurrBank(resultSet.getString("m_curr_bank"));
							a.setCurrAccNo(resultSet.getString("m_curr_no"));
							a.setCurrAvgDeposit(resultSet.getString("m_curr_avg_deposit"));
							a.setCurrAvgDepositDtl(resultSet.getString("m_curr_dtl_deposit"));
							a.setAmexAuthSign(resultSet.getString("m_amex_auth_sign"));
							a.setGst_registration(resultSet.getString("m_gst_registration"));
							a.setRmcd_approval_no(resultSet.getString("m_rmcd_approval_no"));
							
							return a;
						}
					} finally {
						resultSet.close();
					}
					
				} finally {
					statement.close();
				}
				
			} finally {
				connMgr.freeConnection(connectionPool, conn);
			}
			
			this.message = "Merchant not found.";
			return null;
			
		} catch (Exception e){
			this.message = e.getMessage();
			return null;
		}
	}
	
	
	public boolean editMerchantCase(int merchant_id, int case_id, TreeMap<String, String> post, String user){
		try {
	        int TIMEOUT = 10000; //DB connection timeout if unable to get connection in less than 10 seconds
	        String connectionPool = ConfigManager.getInstance().getConnectionPool();
	        DBConnectionManager connMgr = DBConnectionManager.getInstance();
	        try { TIMEOUT = Integer.parseInt(ConfigManager.getInstance().get(Constants.DB_WAIT_TIME)); } catch (Exception e) {}
	        Connection conn = connMgr.getConnection(connectionPool, TIMEOUT);
			
			try {
				String sql = "update merchant set m_modified_date = sysdate, m_modified_by = ?, ";
				
				if(post.get("ownership_status") != null) {
					sql += "m_ownership_status = ?, ";
				}
				
				if(post.get("registered_name") != null) {
					sql += "m_name = ?, ";
				}
				
				if(post.get("registered_no") != null) {
					sql += "m_reg_no = ?, ";
				}
				
				if(post.get("desc") != null) {
					sql += "m_desc = ?, ";
				}
				
				if(post.get("mcc_code") != null) {
					sql += "m_mcc_code = ?, ";
				}
				
				if(post.get("paid_up_capital") != null) {
					sql += "m_paid_up_capital = ?, ";
				}
				
				if(post.get("recall_barcode") != null) {
					sql += "m_recall_barcode = ?, ";
				}
				
				if(post.get("year_in_business") != null) {
					sql += "m_year_in_business = ?, ";
				}
				
				if(post.get("avg_ticket_size") != null) {
					sql += "m_avg_ticket_size = ?, ";
				}
				
				if(post.get("curr_bank") != null) {
					sql += "m_curr_bank = ?, ";
				}
				
				if(post.get("curr_acc_no") != null) {
					sql += "m_curr_no = ?, ";
				}
				
				if(post.get("curr_avg_deposit") != null) {
					sql += "m_curr_avg_deposit = ?, ";
				}
				
				if(post.get("curr_avg_deposit_dtl") != null) {
					sql += "m_curr_dtl_deposit = ?, ";
				}
				
				if(post.get("amex_auth_sign") != null) {
					sql += "m_amex_auth_sign = ?, ";
				}
				
				if(post.get("match_trace") != null) {
					sql += "m_match_trace = ?, ";
				}
				
				if(post.get("gst_registration") != null) {
					sql += "m_gst_registration = ?, ";
				}
				
				if(post.get("rmcd_approval_no") != null) {
					sql += "m_rmcd_approval_no = ?, ";
				}
				
				sql = sql.substring(0, sql.lastIndexOf(','));
				
				sql += " where m_id = ?";
				
				PreparedStatement statement = conn.prepareStatement(sql);
				
				try {
					int paramIndex = 1;
					statement.setString(paramIndex++, user);
					
					if(post.get("ownership_status") != null) {
						statement.setString(paramIndex++, post.get("ownership_status"));
					}
					
					if(post.get("registered_name") != null) {
						statement.setString(paramIndex++, post.get("registered_name"));
					}
					
					if(post.get("registered_no") != null) {
						statement.setString(paramIndex++, post.get("registered_no"));
					}
					
					if(post.get("desc") != null) {
						statement.setString(paramIndex++, post.get("desc"));
					}
					
					if(post.get("mcc_code") != null) {
						statement.setString(paramIndex++, post.get("mcc_code"));
					}
					
					if(post.get("paid_up_capital") != null) {
						statement.setDouble(paramIndex++, (post.get("paid_up_capital").length() <= 0 ? 0.00 : Double.parseDouble(post.get("paid_up_capital"))));
					}
					
					if(post.get("recall_barcode") != null) {
						statement.setString(paramIndex++, post.get("recall_barcode"));
					}
					
					if(post.get("year_in_business") != null) {
						statement.setString(paramIndex++, post.get("year_in_business"));
					}
					
					if(post.get("avg_ticket_size") != null) {
						statement.setString(paramIndex++, post.get("avg_ticket_size"));
					}
					
					if(post.get("curr_bank") != null) {
						statement.setString(paramIndex++, post.get("curr_bank"));
					}
					
					if(post.get("curr_acc_no") != null) {
						statement.setString(paramIndex++, post.get("curr_acc_no"));
					}
					
					if(post.get("curr_avg_deposit") != null) {
						statement.setDouble(paramIndex++, (post.get("curr_avg_deposit").length() <= 0 ? 0.00 : Double.parseDouble(post.get("curr_avg_deposit"))));
					}
					
					if(post.get("curr_avg_deposit_dtl") != null) {
						statement.setString(paramIndex++, post.get("curr_avg_deposit_dtl"));
					}
		
					if(post.get("amex_auth_sign") != null) {
						statement.setString(paramIndex++, post.get("amex_auth_sign"));
					}
					
					if(post.get("match_trace") != null) {
						statement.setString(paramIndex++, post.get("match_trace"));
					}
					
					if(post.get("gst_registration") != null) {
						statement.setString(paramIndex++, post.get("gst_registration"));
					}
					
					if(post.get("rmcd_approval_no") != null) {
						statement.setString(paramIndex++, post.get("rmcd_approval_no"));
					}
					statement.setInt(paramIndex, merchant_id);
					
					statement.execute();
				} finally {
					statement.close();
				}
				
				
				Merchant merchant = this.getMerchant(merchant_id);
				if(merchant == null){
					//this.message = "Failed to aggregate Business Detail data.";
					return false;
				}
				
				JSONObject merchant_dtl_obj = new JSONObject();
				merchant_dtl_obj.put("ownership_status", merchant.getOwnershipStatus());
				merchant_dtl_obj.put("registered_name", merchant.getRegisteredName());
				merchant_dtl_obj.put("registered_no", merchant.getRegisteredNo());
				merchant_dtl_obj.put("desc", merchant.getDesc());
				merchant_dtl_obj.put("mcc_code", merchant.getMCCCode());
				merchant_dtl_obj.put("paid_up_capital", merchant.getPaidUpCapital());
				merchant_dtl_obj.put("recall_barcode", merchant.getRecallBarcode());
				merchant_dtl_obj.put("year_in_business", merchant.getYearInBusiness());
				merchant_dtl_obj.put("avg_ticket_size", merchant.getAvgTicketSize());
				merchant_dtl_obj.put("curr_bank", merchant.getCurrBank());
				merchant_dtl_obj.put("curr_acc_no", merchant.getCurrAccNo());
				merchant_dtl_obj.put("curr_avg_deposit", merchant.getCurrAvgDeposit());
				merchant_dtl_obj.put("gst_registration", merchant.getGst_registration());
				merchant_dtl_obj.put("rmcd_approval_no", merchant.getRmcd_approval_no());
				
				JSONArray avg_deposit_json = (JSONArray)JSONValue.parse(merchant.getCurrAvgDepositDtl());
				merchant_dtl_obj.put("curr_avg_deposit_dtl", avg_deposit_json);
				
				String merchant_dtl = merchant_dtl_obj.toString();
				
				sql = "update casemast set c_merchant_details = ?, c_modified_date = sysdate, c_modified_by = ?, c_status_match_trace = '00',";
				
				if(post.get("app_type") != null) {
					sql += "c_type = ?, ";
				}
				
				if(post.get("acquirer") != null) {
					sql += "c_acquirer = ?, ";
				}
				
				if(post.get("amex_auth_sign") != null) {
					sql += "c_amex_auth_sign = ?, ";
				}
				
				if(post.get("match_trace") != null) {
					sql += "c_match_trace = ?, ";
				}
				
				sql = sql.substring(0, sql.lastIndexOf(','));
				
				sql += " where c_id = ?";
				
				
				statement = conn.prepareStatement(sql);
				
				try {
					int paramIndex = 1;
					statement.setString(paramIndex++, merchant_dtl);
					statement.setString(paramIndex++, user);
					
					if(post.get("app_type") != null) {
						statement.setString(paramIndex++, post.get("app_type"));
					}
					
					if(post.get("acquirer") != null) {
						statement.setString(paramIndex++, post.get("acquirer"));
					}
					
					if(post.get("amex_auth_sign") != null) {
						statement.setString(paramIndex++, post.get("amex_auth_sign"));
					}
					
					if(post.get("match_trace") != null) {
						statement.setString(paramIndex++, post.get("match_trace"));
					}
					
					statement.setInt(paramIndex, case_id);
					
					statement.execute();
				} finally {
					statement.close();
				}
				
				return true;
				
			} finally {
				connMgr.freeConnection(connectionPool, conn);
			}
			
		} catch (Exception e){
			this.message = e.getMessage();
			return false;
		}
	}
	
	
	public boolean editCaseDocumentChecklist(int case_id, String document_checklist, String user_id){
		try {
	        int TIMEOUT = 10000; //DB connection timeout if unable to get connection in less than 10 seconds
	        String connectionPool = ConfigManager.getInstance().getConnectionPool();
	        DBConnectionManager connMgr = DBConnectionManager.getInstance();
	        try { TIMEOUT = Integer.parseInt(ConfigManager.getInstance().get(Constants.DB_WAIT_TIME)); } catch (Exception e) {}
	        Connection conn = connMgr.getConnection(connectionPool, TIMEOUT);
			
			try {
				String sql = "update casemast set c_document_checklist = ?, "
						+ "	c_modified_date = sysdate, "
						+ "	c_modified_by = ? "
						+ "where c_id = ? ";
				
				PreparedStatement statement = conn.prepareStatement(sql);
				
				try {
					statement.setString(1, document_checklist);
					statement.setString(2, user_id);
					statement.setInt(3, case_id);
					
		            statement.execute();
				} finally {
					statement.close();
				}
				
			} finally {
				connMgr.freeConnection(connectionPool, conn);
			}
			
			return true;
			
		} catch (Exception e){
			this.message = e.getMessage();
			return false;
		}
	}
	
	
	public boolean sendMatchTrace(int merchant_id, int case_id, TreeMap<String, String> post, String user, String groupCode){
		Casemast c = CasemastFactory.getCaseMast(groupCode, case_id);
		if(c == null){
			this.message = CasemastFactory.getMessage();
			return false;
		}
		
		c.loadOutlets();
		
		ArrayList<CaseOutlet> c_outlets = c.getOutlets();
		
		SimpleDateFormat d = new SimpleDateFormat("yyyyDHHmmss");
		String dstr = d.format(new Date());
		
		String match_key = "0002121411101901";
		String txn_code = "MI";
		String txn_class = "80";
		String status = "";
		String network_ind = "T";
		String trans_direction = "O";
		String trans_init_ind = "A";
		String card_owner_ind = "";
		String intchg_type_ind = "";
		String ch_posting_ind = "";
		String mer_posting_ind = "";
		String gl_posting_ind = "";
		String cdm_posting_ind = "";
		String filler_1 = "";
		String error_code = "";
		String warning_code = "";
		String warning_1 = "";
		String warning_2 = "";
		String error_location = "";
		String created_operator_id = "";
		String created_timestamp = dstr;
		String updated_operator_id = "";
		String updated_timestamp = dstr;
		String parent_key = "";
		String memo_ind = "";
		
		String destination_id = "00000000000";
		String originator_id = "00000000000";
		String acquiring_inst_id = "";
		
		if(c.getCountryCode().equals("MY")){
			acquiring_inst_id = "027";
		} else if(c.getCountryCode().equals("SG")){
			acquiring_inst_id = "102";
		} else if(c.getCountryCode().equals("PH")){
			acquiring_inst_id = "101";
		} else if(c.getCountryCode().equals("KH")){
			acquiring_inst_id = "103";
		}
		
		String acquiring_sub_inst_id = "";
		String owner_tag = "A";
		String filler_2 = "";
		
		String tran_code = "651";
		String action = "I";
		String acn_filler = "000";
		String acn_ica = "2124";
		String mrchant_id = "";
		String business_name = c.getMerchant().getRegisteredName();
		String dba = "";
		String street_addr_1 = "";
		String street_addr_2 = "";
		String city = "";
		String state = "";
		String zip = "";
		String country = "";
		String business_phone = "";
		String state_tax_nbr = "";
		String natl_tax_id = "";
		String filler_3 = "";
		String transaction_data = "300001";
		
		String mcc = "";
		String date_opened = "";
		String date_closed = "";
		String reason_code = "";
		String cat_ind = "";
		String comments = "";
		String filler_4 = "";
		
		String phonetic_match_req = "";
		String trans_ref = "";
		String region_search_1 = "";
		String region_search_2 = "";
		String region_search_3 = "";
		String region_search_4 = "";
		String region_search_5 = "";
		String region_search_6 = "";
		String country_search_1 = "";
		String country_search_2 = "";
		String country_search_3 = "";
		String country_search_4 = "";
		String country_search_5 = "";
		String country_search_6 = "";
		String country_search_7 = "";
		String country_search_8 = "";
		String country_search_9 = "";
		String country_search_10 = "";
		String filler_5 = "";
		
		String pr1_name_last = "";
		String pr1_name_first = "";
		String pr1_name_mid = "";
		String pr1_street_addr1 = "";
		String pr1_street_addr2 = "";
		String pr1_city = "";
		String pr1_state = "";
		String pr1_zip = "";
		String pr1_country = "";
		String pr1_phone = "";
		String pr1_natl_id = "";
		String pr1_license_id = "";
		String pr1_license_state = "";
		String pr1_license_country = "";
		
		String pr2_name_last = "";
		String pr2_name_first = "";
		String pr2_name_mid = "";
		String pr2_street_addr1 = "";
		String pr2_street_addr2 = "";
		String pr2_city = "";
		String pr2_state = "";
		String pr2_zip = "";
		String pr2_country = "";
		String pr2_phone = "";
		String pr2_natl_id = "";
		String pr2_license_id = "";
		String pr2_license_state = "";
		String pr2_license_country = "";
		
		String pr3_name_last = "";
		String pr3_name_first = "";
		String pr3_name_mid = "";
		String pr3_street_addr1 = "";
		String pr3_street_addr2 = "";
		String pr3_city = "";
		String pr3_state = "";
		String pr3_zip = "";
		String pr3_country = "";
		String pr3_phone = "";
		String pr3_natl_id = "";
		String pr3_license_id = "";
		String pr3_license_state = "";
		String pr3_license_country = "";
		
		String pr4_name_last = "";
		String pr4_name_first = "";
		String pr4_name_mid = "";
		String pr4_street_addr1 = "";
		String pr4_street_addr2 = "";
		String pr4_city = "";
		String pr4_state = "";
		String pr4_zip = "";
		String pr4_country = "";
		String pr4_phone = "";
		String pr4_natl_id = "";
		String pr4_license_id = "";
		String pr4_license_state = "";
		String pr4_license_country = "";
		
		String pr5_name_last = "";
		String pr5_name_first = "";
		String pr5_name_mid = "";
		String pr5_street_addr1 = "";
		String pr5_street_addr2 = "";
		String pr5_city = "";
		String pr5_state = "";
		String pr5_zip = "";
		String pr5_country = "";
		String pr5_phone = "";
		String pr5_natl_id = "";
		String pr5_license_id = "";
		String pr5_license_state = "";
		String pr5_license_country = "";
		
		String filler_6 = "";
		
		
		for(CaseOutlet c_outlet : c_outlets){
			JSONObject obj = (JSONObject) JSONValue.parse(c_outlet.getOutlet().getAddress());
			
			String line_1 = (obj.get("line_1") == null) ? "" : obj.get("line_1").toString().trim();
			String line_2 = (obj.get("line_2") == null) ? "" : obj.get("line_2").toString().trim();
			String postal_code = (obj.get("postal_code") == null) ? "" : obj.get("postal_code").toString().trim();
			String line_city = (obj.get("city") == null) ? "" : obj.get("city").toString().trim();
			
			dba = c_outlet.getOutlet().getName();
			street_addr_1 = line_1;
			street_addr_2 = line_2;
			city = line_city;
			state = c.getCountryCode();
			zip = postal_code;
			
			if(c.getCountryCode().equals("MY")){
				country = "MYS";
			} else if(c.getCountryCode().equals("SG")){
				country = "SGP";
			} else if(c.getCountryCode().equals("PH")){
				country = "PHL";
			} else if(c.getCountryCode().equals("KH")){
				country = "KHM";
			} else {
				country = c.getCountryCode();
			}
			
			business_phone = c_outlet.getOutlet().getCTTel();
			
			break;
		}
		
		
		try {
			InputStream stream = MerchantFactory.class.getResourceAsStream(CONFIG_FILE);
			if (stream != null){
				appCfg.load(stream);
			} else {
				System.out.println("MerchantFactory.sendMatchTrace Input Stream is NULL");
			}
			
			
			String mt_path = appCfg.getProperty("Match_Trace_Path");
			PrintWriter out = new PrintWriter(mt_path + "/" + c.getReferenceNo() + ".txt");
			
			
			try {
				String match_trace = c.getMerchant().getMatchTrace();
				JSONArray arr = (JSONArray) JSONValue.parse(match_trace);
				
				boolean mt_send = false;
				int k = 0;
				
				while(k < arr.size()) {
					k++;
					
					int n = k - 1; System.out.println("***" + n);
					String string = arr.get(n).toString();
			    	JSONObject obj = (JSONObject)JSONValue.parse(string);
			    	
			    	String f_name = (obj.get("f_name") == null) ? "" : obj.get("f_name").toString().trim();
			    	String l_name = (obj.get("l_name") == null) ? "" : obj.get("l_name").toString().trim();
			    	String ic = (obj.get("ic") == null) ? "" : obj.get("ic").toString().trim();
			    	String country_code = (obj.get("country_code") == null) ? "" : obj.get("country_code").toString().trim();
			    	
			    	int mod_5 = k % 5;
			    	
			    	switch(mod_5){
			    	case 1:
			    		pr1_name_last = l_name;
			    		pr1_name_first = f_name;
			    		pr1_country = country_code;
			    		pr1_license_country = country_code;
			    		
			    		if(country_code.equals("MYS")){
			    			pr1_natl_id = "";
			    			pr1_license_id = ic;
			    		} 
			    		else {
			    			pr1_natl_id = ic;
			    			pr1_license_id = "";
			    		}
			    		
			    		break;
			    		
			    	case 2:
			    		pr2_name_last = l_name;
			    		pr2_name_first = f_name;
			    		pr2_country = country_code;
			    		pr2_license_country = country_code;
			    		
			    		if(country_code.equals("MYS")){
			    			pr2_natl_id = "";
			    			pr2_license_id = ic;
			    		} 
			    		else {
			    			pr2_natl_id = ic;
			    			pr2_license_id = "";
			    		}
			    		
			    		break;
			    		
			    	case 3:
			    		pr3_name_last = l_name;
			    		pr3_name_first = f_name;
			    		pr3_country = country_code;
			    		pr3_license_country = country_code;
			    		
			    		if(country_code.equals("MYS")){
			    			pr3_natl_id = "";
			    			pr3_license_id = ic;
			    		} 
			    		else {
			    			pr3_natl_id = ic;
			    			pr3_license_id = "";
			    		}
			    		
			    		break;
			    		
			    	case 4:
			    		pr4_name_last = l_name;
			    		pr4_name_first = f_name;
			    		pr4_country = country_code;
			    		pr4_license_country = country_code;
			    		
			    		if(country_code.equals("MYS")){
			    			pr4_natl_id = "";
			    			pr4_license_id = ic;
			    		} 
			    		else {
			    			pr4_natl_id = ic;
			    			pr4_license_id = "";
			    		}
			    		
			    		break;
			    		
			    	case 0:
			    		pr5_name_last = l_name;
			    		pr5_name_first = f_name;
			    		pr5_country = country_code;
			    		pr5_license_country = country_code;
			    		
			    		if(country_code.equals("MYS")){
			    			pr5_natl_id = "";
			    			pr5_license_id = ic;
			    		} 
			    		else {
			    			pr5_natl_id = ic;
			    			pr5_license_id = "";
			    		}
			    		
			    		
			    		mt_send = true;
			    		
			    		break;
			    		
		    		default:
		    			break;
			    	}
			    	
			    	
			    	
			    	if(mt_send == false){
			    		if(k == arr.size()){
			    			mt_send = true;
			    		}
			    	}
			    	
			    	if(mt_send == true){
			    		match_key = String.format("%1$-16s", match_key.trim());
						txn_code = String.format("%1$-2s", txn_code.trim());
						txn_class = String.format("%1$-2s", txn_class.trim());
						status = String.format("%1$-1s", status.trim());
						network_ind = String.format("%1$-1s", network_ind.trim());
						trans_direction = String.format("%1$-1s", trans_direction.trim());
						trans_init_ind = String.format("%1$-1s", trans_init_ind.trim());
						card_owner_ind = String.format("%1$-1s", card_owner_ind.trim());
						intchg_type_ind = String.format("%1$-1s", intchg_type_ind.trim());
						ch_posting_ind = String.format("%1$-1s", ch_posting_ind.trim());
						mer_posting_ind = String.format("%1$-1s", mer_posting_ind.trim());
						gl_posting_ind = String.format("%1$-1s", gl_posting_ind.trim());
						cdm_posting_ind = String.format("%1$-1s", cdm_posting_ind.trim());
						filler_1 = String.format("%1$-3s", filler_1.trim());
						error_code = String.format("%1$-3s", error_code.trim());
						warning_code = String.format("%1$-6s", warning_code.trim());
						warning_1 = String.format("%1$-3s", warning_1.trim());
						warning_2 = String.format("%1$-3s", warning_2.trim());
						error_location = String.format("%1$-1s", error_location.trim());
						created_operator_id = String.format("%1$-20s", created_operator_id.trim());
						created_timestamp = String.format("%1$-13s", created_timestamp.trim());
						updated_operator_id = String.format("%1$-20s", updated_operator_id.trim());
						updated_timestamp = String.format("%1$-13s", updated_timestamp.trim());
						parent_key = String.format("%1$-16s", parent_key.trim());
						memo_ind = String.format("%1$-1s", memo_ind.trim());
						
						destination_id = String.format("%1$-11s", destination_id.trim());
						originator_id = String.format("%1$-11s", originator_id.trim());
						acquiring_inst_id = String.format("%1$-11s", acquiring_inst_id.trim());
						acquiring_sub_inst_id = String.format("%1$-11s", acquiring_sub_inst_id.trim());
						owner_tag = String.format("%1$-1s", owner_tag.trim());
						filler_2 = String.format("%1$-19s", filler_2.trim());
						
						tran_code = String.format("%1$-3s", tran_code.trim());
						action = String.format("%1$-1s", action.trim());
						acn_filler = String.format("%1$-3s", acn_filler.trim());
						acn_ica = String.format("%1$-4s", acn_ica.trim());
						mrchant_id = String.format("%1$-15s", mrchant_id.trim());
						business_name = String.format("%1$-30s", business_name.trim());
						dba = String.format("%1$-30s", dba.trim());
						street_addr_1 = String.format("%1$-30s", street_addr_1.trim());
						street_addr_2 = String.format("%1$-30s", street_addr_2.trim());
						city = String.format("%1$-15s", city.trim());
						state = String.format("%1$-2s", state.trim());
						zip = String.format("%1$-10s", zip.trim());
						country = String.format("%1$-3s", country.trim());
						business_phone = String.format("%1$-10s", business_phone.trim());
						state_tax_nbr = String.format("%1$-9s", state_tax_nbr.trim());
						natl_tax_id = String.format("%1$-9s", natl_tax_id.trim());
						filler_3 = String.format("%1$-16s", filler_3.trim());
						transaction_data = String.format("%1$-240s", transaction_data.trim());
						
						mcc = String.format("%1$-4s", mcc.trim());
						date_opened = String.format("%1$-8s", date_opened.trim());
						date_closed = String.format("%1$-8s", date_closed.trim());
						reason_code = String.format("%1$-2s", reason_code.trim());
						cat_ind = String.format("%1$-1s", cat_ind.trim());
						comments = String.format("%1$-200s", comments.trim());
						filler_4 = String.format("%1$-17s", filler_4.trim());
						
						phonetic_match_req = String.format("%1$-1s", phonetic_match_req.trim());
						trans_ref = String.format("%1$-5s", trans_ref.trim());
						region_search_1 = String.format("%1$-3s", region_search_1.trim());
						region_search_2 = String.format("%1$-3s", region_search_2.trim());
						region_search_3 = String.format("%1$-3s", region_search_3.trim());
						region_search_4 = String.format("%1$-3s", region_search_4.trim());
						region_search_5 = String.format("%1$-3s", region_search_5.trim());
						region_search_6 = String.format("%1$-3s", region_search_6.trim());
						country_search_1 = String.format("%1$-3s", country_search_1.trim());
						country_search_2 = String.format("%1$-3s", country_search_2.trim());
						country_search_3 = String.format("%1$-3s", country_search_3.trim());
						country_search_4 = String.format("%1$-3s", country_search_4.trim());
						country_search_5 = String.format("%1$-3s", country_search_5.trim());
						country_search_6 = String.format("%1$-3s", country_search_6.trim());
						country_search_7 = String.format("%1$-3s", country_search_7.trim());
						country_search_8 = String.format("%1$-3s", country_search_8.trim());
						country_search_9 = String.format("%1$-3s", country_search_9.trim());
						country_search_10 = String.format("%1$-3s", country_search_10.trim());
						filler_5 = String.format("%1$-186s", filler_5.trim());
						
						
						pr1_name_last = String.format("%1$-25s", pr1_name_last.trim());
						pr1_name_first = String.format("%1$-15s", pr1_name_first.trim());
						pr1_name_mid = String.format("%1$-1s", pr1_name_mid.trim());
						pr1_street_addr1 = String.format("%1$-30s", pr1_street_addr1.trim());
						pr1_street_addr2 = String.format("%1$-30s", pr1_street_addr2.trim());
						pr1_city = String.format("%1$-15s", pr1_city.trim());
						pr1_state = String.format("%1$-2s", pr1_state.trim());
						pr1_zip = String.format("%1$-10s", pr1_zip.trim());
						pr1_country = String.format("%1$-3s", pr1_country.trim());
						pr1_phone = String.format("%1$-10s", pr1_phone.trim());
						pr1_natl_id = String.format("%1$-9s", pr1_natl_id.trim());
						pr1_license_id = String.format("%1$-25s", pr1_license_id.trim());
						pr1_license_state = String.format("%1$-2s", pr1_license_state.trim());
						pr1_license_country = String.format("%1$-3s", pr1_license_country.trim());
						
						pr2_name_last = String.format("%1$-25s", pr2_name_last.trim());
						pr2_name_first = String.format("%1$-15s", pr2_name_first.trim());
						pr2_name_mid = String.format("%1$-1s", pr2_name_mid.trim());
						pr2_street_addr1 = String.format("%1$-30s", pr2_street_addr1.trim());
						pr2_street_addr2 = String.format("%1$-30s", pr2_street_addr2.trim());
						pr2_city = String.format("%1$-15s", pr2_city.trim());
						pr2_state = String.format("%1$-2s", pr2_state.trim());
						pr2_zip = String.format("%1$-10s", pr2_zip.trim());
						pr2_country = String.format("%1$-3s", pr2_country.trim());
						pr2_phone = String.format("%1$-10s", pr2_phone.trim());
						pr2_natl_id = String.format("%1$-9s", pr2_natl_id.trim());
						pr2_license_id = String.format("%1$-25s", pr2_license_id.trim());
						pr2_license_state = String.format("%1$-2s", pr2_license_state.trim());
						pr2_license_country = String.format("%1$-3s", pr2_license_country.trim());
						
						pr3_name_last = String.format("%1$-25s", pr3_name_last.trim());
						pr3_name_first = String.format("%1$-15s", pr3_name_first.trim());
						pr3_name_mid = String.format("%1$-1s", pr3_name_mid.trim());
						pr3_street_addr1 = String.format("%1$-30s", pr3_street_addr1.trim());
						pr3_street_addr2 = String.format("%1$-30s", pr3_street_addr2.trim());
						pr3_city = String.format("%1$-15s", pr3_city.trim());
						pr3_state = String.format("%1$-2s", pr3_state.trim());
						pr3_zip = String.format("%1$-10s", pr3_zip.trim());
						pr3_country = String.format("%1$-3s", pr3_country.trim());
						pr3_phone = String.format("%1$-10s", pr3_phone.trim());
						pr3_natl_id = String.format("%1$-9s", pr3_natl_id.trim());
						pr3_license_id = String.format("%1$-25s", pr3_license_id.trim());
						pr3_license_state = String.format("%1$-2s", pr3_license_state.trim());
						pr3_license_country = String.format("%1$-3s", pr3_license_country.trim());
						
						pr4_name_last = String.format("%1$-25s", pr4_name_last.trim());
						pr4_name_first = String.format("%1$-15s", pr4_name_first.trim());
						pr4_name_mid = String.format("%1$-1s", pr4_name_mid.trim());
						pr4_street_addr1 = String.format("%1$-30s", pr4_street_addr1.trim());
						pr4_street_addr2 = String.format("%1$-30s", pr4_street_addr2.trim());
						pr4_city = String.format("%1$-15s", pr4_city.trim());
						pr4_state = String.format("%1$-2s", pr4_state.trim());
						pr4_zip = String.format("%1$-10s", pr4_zip.trim());
						pr4_country = String.format("%1$-3s", pr4_country.trim());
						pr4_phone = String.format("%1$-10s", pr4_phone.trim());
						pr4_natl_id = String.format("%1$-9s", pr4_natl_id.trim());
						pr4_license_id = String.format("%1$-25s", pr4_license_id.trim());
						pr4_license_state = String.format("%1$-2s", pr4_license_state.trim());
						pr4_license_country = String.format("%1$-3s", pr4_license_country.trim());
						
						pr5_name_last = String.format("%1$-25s", pr5_name_last.trim());
						pr5_name_first = String.format("%1$-15s", pr5_name_first.trim());
						pr5_name_mid = String.format("%1$-1s", pr5_name_mid.trim());
						pr5_street_addr1 = String.format("%1$-30s", pr5_street_addr1.trim());
						pr5_street_addr2 = String.format("%1$-30s", pr5_street_addr2.trim());
						pr5_city = String.format("%1$-15s", pr5_city.trim());
						pr5_state = String.format("%1$-2s", pr5_state.trim());
						pr5_zip = String.format("%1$-10s", pr5_zip.trim());
						pr5_country = String.format("%1$-3s", pr5_country.trim());
						pr5_phone = String.format("%1$-10s", pr5_phone.trim());
						pr5_natl_id = String.format("%1$-9s", pr5_natl_id.trim());
						pr5_license_id = String.format("%1$-25s", pr5_license_id.trim());
						pr5_license_state = String.format("%1$-2s", pr5_license_state.trim());
						pr5_license_country = String.format("%1$-3s", pr5_license_country.trim());
						
						filler_6 = String.format("%1$-50s", filler_6.trim());
						
						
						String data_p = match_key + txn_code + txn_class + status + network_ind + trans_direction + trans_init_ind + card_owner_ind + intchg_type_ind + ch_posting_ind + mer_posting_ind + gl_posting_ind + cdm_posting_ind + filler_1 + error_code + warning_code + warning_1 + warning_2 + error_location + created_operator_id + created_timestamp + updated_operator_id + updated_timestamp + parent_key + memo_ind 
								+ destination_id + originator_id + acquiring_inst_id + acquiring_sub_inst_id + owner_tag + filler_2 
								+ tran_code + action + acn_filler + acn_ica + mrchant_id + business_name + dba + street_addr_1 + street_addr_2 + city + state + zip + country + business_phone + state_tax_nbr + natl_tax_id + filler_3 + transaction_data 
								+ mcc + date_opened + date_closed + reason_code + cat_ind + comments + filler_4 
								+ phonetic_match_req + trans_ref + region_search_1 + region_search_2 + region_search_3 + region_search_4 + region_search_5 + region_search_6 + country_search_1 + country_search_2 + country_search_3 + country_search_4 + country_search_5 + country_search_6 + country_search_7 + country_search_8 + country_search_9 + country_search_10 + filler_5 
								+ pr1_name_last + pr1_name_first + pr1_name_mid + pr1_street_addr1 + pr1_street_addr2 + pr1_city + pr1_state + pr1_zip + pr1_country + pr1_phone + pr1_natl_id + pr1_license_id + pr1_license_state + pr1_license_country 
								+ pr2_name_last + pr2_name_first + pr2_name_mid + pr2_street_addr1 + pr2_street_addr2 + pr2_city + pr2_state + pr2_zip + pr2_country + pr2_phone + pr2_natl_id + pr2_license_id + pr2_license_state + pr2_license_country 
								+ pr3_name_last + pr3_name_first + pr3_name_mid + pr3_street_addr1 + pr3_street_addr2 + pr3_city + pr3_state + pr3_zip + pr3_country + pr3_phone + pr3_natl_id + pr3_license_id + pr3_license_state + pr3_license_country 
								+ pr4_name_last + pr4_name_first + pr4_name_mid + pr4_street_addr1 + pr4_street_addr2 + pr4_city + pr4_state + pr4_zip + pr4_country + pr4_phone + pr4_natl_id + pr4_license_id + pr4_license_state + pr4_license_country 
								+ pr5_name_last + pr5_name_first + pr5_name_mid + pr5_street_addr1 + pr5_street_addr2 + pr5_city + pr5_state + pr5_zip + pr5_country + pr5_phone + pr5_natl_id + pr5_license_id + pr5_license_state + pr5_license_country + filler_6;
						
						out.println(data_p);
						
			    	}
				}
			} 
			catch (Exception e) {
				e.printStackTrace();
			} 
			finally {
				out.close();
			}
			
			
			
			return true;
			
		} catch (Exception e){
			this.message = e.getMessage();
			return false;
		}
	}
}
